package typex

/*
https://chai2010.cn/advanced-go-programming-book/ch2-cgo/ch2-03-cgo-types.html

在 CGO 生成的 _cgo_export.h 头文件中还会为 Go 语言的字符串、切片、字典、接口和管道等特有的数据类型生成对应的 C 语言类型

typedef struct {const char *p; GoInt n;} GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct {void *t; void *v;} GoInterface;
typedef struct {void *data; GoInt len; GoInt cap;} GoSlice;


其中只有字符串和切片在 CGO 中有一定的使用价值，
因为 CGO 为他们的某些 GO 语言版本的操作函数生成了 C 语言版本，因此二者可以在 Go 调用 C 语言函数时马上使用; 而 CGO 并未针对其他的类型提供相关的辅助函数，且 Go 语言特有的内存模型导致我们无法保持这些由 Go 语言管理的内存指针，所以它们 C 语言环境并无使用的价值
*/

/*
C 语言的结构体、联合、枚举类型不能作为匿名成员被嵌入到 Go 语言的结构体中
Go 语言中，我们可以通过 C.struct_xxx 来访问 C 语言中定义的 struct xxx 结构体类型

结构体的内存布局按照 C 语言的通用对齐规则,，在 32 位 Go 语言环境 C 语言结构体也按照 32 位对齐规则，在 64 位 Go 语言环境按照 64 位的对齐规则。对于指定了特殊对齐规则的结构体，无法在 CGO 中访问。


1，结构体成员以 {Go keyword } 命名,--> 自动转至 _keyword
2，结构体 C {
 Go keyword //被屏蔽
 Go _keyword
},
刚好是以下划线和 Go 语言关键字命名，那么以 Go 语言关键字命名的成员将无法访问（被屏蔽）
*/

/*
struct A {
    int i;
    float f;
    int   type;  // type 是 Go 语言的关键字
 	float _type; // 将屏蔽 CGO 对 type 成员的访问
};
*/
import "C"
import (
	"fmt"
	"reflect"
	"unsafe"

	"github.com/gookit/color"
)

func StructShow() {
	var a C.struct_A
	fmt.Println(a.i, a.f, reflect.TypeOf(a._type))
	//fmt.Println(a.type, )
	color.Greenln("Sizeof", unsafe.Sizeof(a))
	color.Greenln("Sizeof", unsafe.Sizeof(a.i), "Alignof", unsafe.Alignof(a.i), "Offsetof", unsafe.Offsetof(a.i))
	color.Greenln("Sizeof", unsafe.Sizeof(a.f), "Alignof", unsafe.Alignof(a.f), "Offsetof", unsafe.Offsetof(a.f))
}
